#!/bin/bash

##
# run a test
runTest()
{
    local prog=$1
    shift
    (
    	cd $here/tmp
    	if [ ! -z $EXIV2_ECHO ]; then
			echoTest $VALGRIND $bin$prog "$@"
	fi
	$VALGRIND $bin$prog "$@"
    )
}

##
# echo commands and arguments
echoTest()
{
	local count=1
	for i in $@ ; do
		echo $((count++)):  $i
	done
	echo -----------------------
}

##
# predictate
existsTest()
{
	local prog=$1
	result=0
	if [ -z "$bin" ]; then
		if [ ! -z $(which $prog) ]; then
			result=1
		fi
	else
		if [ -e $bin$prog -o -e $bin$prog.exe ]; then
			result=1
		fi
	fi
	echo $result
}

##
# copy file
copy()
{
	\cp "$1" "$2"
}

##
# copy file from data to tmp (copyTestFile from to)
copyTestFile()
{
	if [ $# == 2 ]; then
		cp -f "$here/data/$1" "$here/tmp/$2"
	elif [ $# == 1 ]; then
		stub=$(basename $1)
		cp -f "$here/data/$1" "$here/tmp/$stub"
	else
		echo "*** error copyTestFile: illegal number of inputs = $# ***"
	fi

}

##
# copy 1 or more files from data to tmp
copyTestFiles()
{
	for i in "$@" ; do
		copyTestFile "$i" "$i"
	done
}

##
# result analysis
reportTest()
{
    cat $results | tr '\\' '/' > ${results}-new
    	mv -f ${results}-new $results
    if [ ! -z `which dos2unix` ]; then
        dos2unix $results >/dev/null 2>&1
    fi

    if [ $# -eq 0 ]; then
        lhs=$results
        rhs=$good
    else
        if [ $# -eq 3 ] ; then
            diffargs=$1
            lhs=$2
            rhs=$3
        else
            lhs=$1
            rhs=$2
        fi
    fi

    if [ "$PLATFORM" == "cygwin" ]; then
        diff -q $diffargs $(cygpath -aw $lhs) $(cygpath -aw $rhs)
    else
        diff -q $diffargs $lhs $rhs
    fi
    rc=$?
    if [ $rc -eq 0 ] ; then
        echo "all testcases passed."
    else
        diff $diffargs $lhs $rhs
	exit 3
    fi
}

##
# moved here from write-test.sh
# Function:
#     runTestCase number file
# Params:
#     number: Test case number
#     file  : Input file
# Abstract:
# Run the requested test case number with the given file
runTestCase()
{
    rtc_number=$1
    rtc_infile=$2

    rtc_outfile=test${rtc_number}.jpg
    rtc_jpgthumb=thumb${rtc_number}.jpg
    rtc_tifthumb=thumb${rtc_number}.tif

    rm -f $rtc_outfile $rtc_jpgthumb $rtc_tifthumb
    rm -f iii ttt;

    echo "------------------------------------------------------------"
    runTest exifprint $rtc_infile > iii;
    cp $rtc_infile $rtc_outfile;
    runTest write-test $rtc_infile $rtc_number > ttt;
    diff -a iii ttt
}

##
# moved here from bugfixes-test.sh
prep_file()
{
    echo `prep_any_file $1 exiv2-bug$1.jpg`
}

prep_empty_file()
{
    echo `prep_any_file $1 exiv2-empty.jpg`
}

prep_any_file()
{
    printf "$1 " >&3
    echo '------>' Bug $1 '<-------' >&2
    copyTestFile $2 exiv2-bug$1.jpg
    echo exiv2-bug$1.jpg
}

##
# moved here from imagetest.sh
eraseTest()
{
    src=$1
    test=${src}.etst
    good=$datapath/${src}.egd

    #setup
    cp $datapath/$src $test

    #run tests
    ${bin}metacopy $test $test

    #check results
    diffCheck $test $good
    printf "."
}

copyTest()
{
    num=$1
    src=$2
    dst=$3
    test=${dst}.c${num}tst
    good=$datapath/${dst}.c${num}gd

    #setup
    cp $datapath/$dst $test

    #run tests
    ${bin}metacopy -a $datapath/$src $test

    #check results
    diffCheck $test $good
    printf "."
}

iptcTest()
{
    num=$1
    src=$2
    dst=$3
    test=${dst}.i${num}tst
    good=$datapath/${dst}.i${num}gd

    #setup
    cp $datapath/$dst $test

    #run tests
    runTest metacopy -ip $datapath/$src $test

    #check results
    diffCheck $test $good
    printf "."
}

# Make sure to pass the test file first and the known good file second
diffCheck()
{
    test=$(real_path $1)
    good=$(real_path $2)
    if [ -z "$errors" ]; then let -a errors=0; fi

    #run diff and check results
    diff -q --binary $diffargs "$test" "$good"
    if [ $? -ne 0 ]; then
       errors=$(expr $errors + 1)
    else
       rm $test
    fi
}


##
# moved here from iotest.sh
ioTest()
{
    src=$datapath/$1
    out1=${1}.1
    out2=${1}.2

    #run tests
    runTest iotest $src $out1 $out2
    if [ $? -ne 0 ]; then
       errors=`expr $errors + 1`
       return
    fi

    #check results
    diffCheck $out1 $src
    diffCheck $out2 $src
    printf "."
}


##
# moved here from iptctest.sh
printTest()
{
    src=$1
    test=${src}.iptst
    good=$datapath/${src}.ipgd

    #run tests
    runTest iptcprint $datapath/$src > $test

    #check results
    diffCheck $test $good
    printf "."
}

removeTest()
{
    src=$1
    tmp="temp"
    test=${src}.irtst
    good=$datapath/${src}.irgd

    #setup
    cp $datapath/$src $tmp

    #run tests
    runTest iptctest $tmp <<-eoc
		r Iptc.Application2.Byline
		r Iptc.Application2.Caption
		r Iptc.Application2.Keywords
		r Iptc.Application2.Keywords
		r Iptc.Application2.Keywords
		r Iptc.Application2.CountryName
eoc
    runTest iptcprint $tmp > $test

    #check results
    diffCheck $test $good
    printf "."
    rm $tmp
}

addModTest()
{
    src=$1
    tmp="temp"
    test=${src}.iatst
    good=$datapath/${src}.iagd

    #setup
    cp $datapath/$src $tmp

    #run tests
    runTest iptctest $tmp <<-eoc
		a Iptc.Application2.Headline          The headline I am
		a Iptc.Application2.Keywords          Yet another keyword
		m Iptc.Application2.DateCreated       2004-8-3
		a Iptc.Application2.Urgency           3
		m Iptc.Application2.SuppCategory      "bla bla ba"
		a Iptc.Envelope.ModelVersion          2
		a Iptc.Envelope.TimeSent              14:41:0-05:00
		a Iptc.Application2.RasterizedCaption 230 42 34 2 90 84 23 146
eoc
    runTest iptcprint $tmp > $test

    #check results
    diffCheck $test $good
    printf "."
    rm $tmp
}

extendedTest()
{
    src=$1
    tmp="temp"
    test=${src}.ixtst
    good=$datapath/${src}.ixgd

    #setup
    cp $datapath/$src $tmp

    #run tests
    runTest iptctest $tmp < $datapath/ext.dat
    runTest iptcprint $tmp > $test

    #check results
    diffCheck $test $good
    printf "."
    rm $tmp
}

##
#
hardLinkFiles()
{
	target="$1"
	shift
	for var; do
		if [ -e $var ]; then rm -rf $var ; fi
		ln $target $var
	done
}

##
# real_path - report the absolute path to a file
real_path ()
{
	if [ "$PLATFORM" == "Darwin" -o "$PLATFORM" == "mingw" ]; then
		if [ -d "$1" ]; then
			cd "$1"
			echo $PWD
		else
			cd $(dirname $1)
			echo "$PWD"/$(basename "$1")
		fi
	else
		which realpath 2>/dev/null >/dev/null
		if [ $? == 0 ]; then
			realpath "$1"
		else
			readlink -f "$1"
		fi
    fi
}

copyVideoFiles ()
{
	pushd "$testdir" 2>/dev/null >/dev/null

	##
	# find video files data/video and copy them for testing
	declare -a videos
	for video in $datadir/video/* ; do
		# http://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
		ext="${video##*.}"
		if [ $ext != out ]; then
			copyTestFile "$video"
			videos+=($(basename "$video"))
		fi
	done

	##
	# TODO: remove debugging code
	if [ "$FACTORY" == "rmills-mbp.localXX" ]; then
    	for v in write-video-test.out video-test.out; do
	    	cp ~/gnu/exiv2/testdata/trunk/video/$v ~/gnu/exiv2/video13/test/data/video/
		done
	fi

	# http://stackoverflow.com/questions/7442417/how-to-sort-an-array-in-bash
	# readarray -t sorted < <(printf '%s\0' "${videos[@]}" | sort -z | xargs -0n1)
	# echo ${videos[*]}
	# unset  videos

	popd 2>/dev/null >/dev/null
}

##
# print checksum for one file
checkSum()
{
    # cygwin checksum: http://esrg.sourceforge.net/utils_win_up/md5sum/
    # macOS - built/installed coreutils 8.25 http://ftp.gnu.org/gnu/coreutils/
    platform=$(uname)
    if [ "$platform" == 'NetBSD' -o "$platform" == 'FreeBSD' ]; then
      md5 -q $1
    else
      md5sum $1 | cut -d' ' -f 1
    fi
}

##
# prepare temp files and other variables
prepareTest()
{
	##
	# locale and timezone setting
	export LC_ALL=C
	export TZ=BST-1

	##
	# initialize globals
	this=$(basename $0 .sh)
	here=$PWD
	datapath="../data"
	testdir="$here/tmp"
	datadir="../data"

	if [ -z "$EXIV2_BINDIR" ] ; then
        bin="$here/../build/bin/"
	else
		bin="$EXIV2_BINDIR/"
	fi

	os=$(uname)
	if [ "${os:0:4}" == "CYGW" ]; then
		export PLATFORM=cygwin
	elif [ "${os:0:4}" == "MING" -o "${os:0:4}" == "MSYS" ]; then
		export PLATFORM=mingw
	else
		export PLATFORM=$os
	fi

	if [ "$PLATFORM" == cygwin -o "$PLATFORM" == mingw ]; then
		exe=.exe
	fi

	if [ "$PLATFORM" == cygwin ]; then
		# We need a private version of diff for linux compatibility
		diff()
		{
			args=()
			for i in "$@"; do
				if [ ${i:0:1} != '-' ]; then
					i="$(cygpath -aw $i)"
				fi
				args+=($i)
			done
			DIFF=$(which diff)
			"$DIFF" ${args[@]}
		}
	fi

    ##
    # figure out arguments for diff
    diffargs="--strip-trailing-cr"
    good="$here/data/${this}.out"
    results="$here/tmp/${this}.out"

    tmpfile=$here/tmp/$this
    touch $tmpfile
    diff -q $diffargs $tmpfile $tmpfile 2>/dev/null
    if [ $? -ne 0 ]; then
        diffargs=""
    fi

	tmpfile=tmp/ttt
	touch $tmpfile
	da1="--strip-trailing-cr"
	diff -q $da1 $tmpfile $tmpfile 2>/dev/null
	if [ $? -ne 0 ] ; then
    	da1=""
	fi
	da2="--ignore-matching-lines=^Usage:.*exiv2"
	diff -q $da2 $tmpfile $tmpfile 2>/dev/null
	#if [ $? -ne 0  -o "$PLATFORM" == mingw ] ; then
    #	da2=""
	#fi
	diffargs="$da1 $da2"

    ##
    # test that exiv2 and some sample apps are in the bin!
    for e in exiv2 exifprint easyaccess-test metacopy ; do
		e="${bin}${e}${exe}"
		if [ ! -e "$e" ]; then
			echo '******************************************'
			echo '***' $(real_path "$e") does not exist
			echo '******************************************'
			exit 42
		fi
    done
}

prepareTest

# That's all Folks!
##
